package utils;




public class Polygon {

	/**
	 * member variables
	 */
	 int n;
	 int[] x_points;
	 int[] y_points;
	
	/**
	 * Constructor
	 */
	public Polygon(){
		x_points = new int[4];
		y_points = new int[4];
	}
	
	/**
	 * Constructor with parameters
	 */
	public Polygon(int xpoints[], int ypoints[], int npoints){
		if(npoints > xpoints.length || npoints > ypoints.length){
			throw new IndexOutOfBoundsException("Polygon constructor : npoints larger than xpoints or ypoints");
		}
		this.n = npoints;
		this.x_points = new int[npoints];
		System.arraycopy(xpoints, 0, this.x_points, 0, npoints);
		this.y_points = new int[npoints];
		System.arraycopy(ypoints, 0, this.y_points, 0, npoints);
	}
	
	public void reset() {
		n = 0;
	}
	
	//add a point to the shape
	public void addPoint(int x, int y) {
		if (n == x_points.length) {
			int tmp[];

			tmp = new int[n * 2];
			System.arraycopy(x_points, 0, tmp, 0, n);
			x_points = tmp;

			tmp = new int[n * 2];
			System.arraycopy(y_points, 0, tmp, 0, n);
			y_points = tmp;
		}
		x_points[n] = x;
		y_points[n] = y;
		n++;
	}
	
	//check if shape contains a point
	public boolean contains(int x, int y) {
		if (n <= 2 ){
			return false;
		}
		int hits = 0;

		int lastx = x_points[n - 1];
		int lasty = y_points[n - 1];
		int curx, cury;

		// Walk the edges of the polygon
		for (int i = 0; i < n; lastx = curx, lasty = cury, i++) {
			curx = x_points[i];
			cury = y_points[i];

			if (cury == lasty) {
				continue;
			}

			int leftx;
			if (curx < lastx) {
				if (x >= lastx) {
					continue;
				}
				leftx = curx;
			} else {
				if (x >= curx) {
					continue;
				}
				leftx = lastx;
			}

			double test1, test2;
			if (cury < lasty) {
				if (y < cury || y >= lasty) {
					continue;
				}
				if (x < leftx) {
					hits++;
					continue;
				}
				test1 = x - curx;
				test2 = y - cury;
			} else {
				if (y < lasty || y >= cury) {
					continue;
				}
				if (x < leftx) {
					hits++;
					continue;
				}
				test1 = x - lastx;
				test2 = y - lasty;
			}

			if (test1 < (test2 / (lasty - cury) * (lastx - curx))) {
				hits++;
			}
		}

		return ((hits & 1) != 0);
	}
	
	public float[] getPoints() {
		int size = n * 4;
		float[] points = new float[size];
		int j = 1;

		if ( size == 0 || x_points == null || y_points == null)
			return null;
		
		points[0] = x_points[0];
		points[1] = y_points[0];

		for (int i = 2; i < points.length - 2; i += 4) {

			points[i] = x_points[j];
			points[i + 1] = y_points[j];
			points[i + 2] = x_points[j];
			points[i + 3] = y_points[j];
			j++;
		}
		points[size - 2] = x_points[0];
		points[size - 1] = y_points[0];

		return points;
	}

	public int n(){
		return n;
	}
	
	public int[] x_points(){
		return x_points;
	}
	
	public int[] y_points(){
		return y_points;
	}
}
